package eHealth.android.client;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import eHealth.android.Helpers.MedicalDataItem;
import eHealth.android.Helpers.StatisticsHelper;
import eHealth.android.Helpers.StatisticsProcessingHelper;

/**
 * 
 * @author Thomas Rouvinez
 * Date 18.04.2012
 * 
 * Goal: Show a loading screen to the user while we fetch medical data from the server
 * and bake statistics out of it.
 *
 */
public class LoadingScreen extends Activity{	

	// -----------------------------------------------------------------------------
	// On Create for Android GUI.
	// -----------------------------------------------------------------------------

	/** Called when the activity is first created.<br>
	 * Set the window size to fullscreen and assign the layout - GUI  */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Set full screen application.
		requestWindowFeature(Window.FEATURE_NO_TITLE);   
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,    
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		// Set content view.
		setContentView(R.layout.loadingasync);
	}

	/** Called when the activity starts once it is created.<br>
	 * Creates a separated thread for processing the data and make 
	 * the GUI wait on it. */
	@Override
	protected void onStart() {
		super.onStart();

		if (Menu.statisticsAlreadyProcessed == false) {
			// Loading the data from server.
			LoadingDataAsync task = new LoadingDataAsync();
			task.execute();
		}
		else{
			loadStatisticIntent();
			closeLoading();
		}
	}

	// -----------------------------------------------------------------------------
	// Inner class for the asynchronous call to the server to get data.
	// -----------------------------------------------------------------------------

	/**
	 * 
	 * @author Iodis
	 * Date 18.04.2012
	 * 
	 * Goal: create a separated thread to fetch and bake statistics out of medical
	 * data array.
	 *
	 */
	private class LoadingDataAsync extends AsyncTask<Void, Integer, StatisticsHelper[]>{
		
		// --------------------------------------------------------------------------------
		// Variables.
		// --------------------------------------------------------------------------------
		
		/**
		 * Array of medical data items.
		 */
		private MedicalDataItem data[];
		
		/**
		 * Array of four statistics storage objects.
		 */
		private StatisticsHelper[] stats = new StatisticsHelper[4];
		
		/**
		 * Boolean value to assess of processing's success.
		 */
		private boolean success = false;

		/**
		 * Separated thread declaration and instructions for processing
		 * the whole statistics' array of StatisticsHelpers.
		 */
		@Override
		protected StatisticsHelper[] doInBackground(Void... params) {

			try {
				// Create connection.
				DefaultHttpClient client = new DefaultHttpClient();
				HttpGet httpGet = new HttpGet(Menu.RESTURIAddRecord);
				httpGet.setHeader("Cookie", "JSESSIONID=" + Menu.key);
				
				// Execute request.
				HttpResponse execute = client.execute(httpGet);
				
				// Convert response to JSON array.
				BufferedReader buffer = new BufferedReader(new InputStreamReader(
						execute.getEntity().getContent(), "UTF-8"));
				
				StringBuilder builder = new StringBuilder();
				
				for (String line = null; (line = buffer.readLine()) != null;) {
				    builder.append(line).append("\n");
				}
				
				JSONTokener tokener = new JSONTokener(builder.toString());
				JSONArray jsonArray = new JSONArray(tokener);
				
				// Convert JSON Array to MedicalDataItem array.
				data = new MedicalDataItem[jsonArray.length()];
				
				MedicalDataItem item;
				JSONObject jsonObject = new JSONObject();

				for(int i = 0 ; i < jsonArray.length() ; i++){
					jsonObject = jsonArray.getJSONObject(i);
					
					if(jsonObject != null){
						item = new MedicalDataItem();
	
						item.setDate(jsonObject.getString("date"));
						item.setType(jsonObject.getInt("type"));
						item.setCategory(jsonObject.getInt("category"));
						item.setValue(jsonObject.getDouble("value"));
						
						data[i] = item;
					}
				}

				// Compute statistics.
				stats[0] = new StatisticsProcessingHelper(data).getStatistics(0); 	// Daily.
				stats[1] = new StatisticsProcessingHelper(data).getStatistics(7); 	// Weekly.
				stats[2] = new StatisticsProcessingHelper(data).getStatistics(30);	// Monthly.
				stats[3] = new StatisticsProcessingHelper(data).getStatistics(90);	// Quarterly.

				// If succeeded.
				Menu.statisticsAlreadyProcessed = true;
				success= true;
			} catch (Exception e) {
			}

			// Return statisticsHelper vector.
			return stats;
		}

		/**
		 * Trigger when the asynchronous call is done. Load next intent and
		 * give it the processed data for display.
		 */
		@Override
		protected void onPostExecute(StatisticsHelper[] data){
			if(success == true){
				// Try-catch here is to ensure the intent is created before we try
				// to give it data.
				try {
					// Load intent for the real statistic page.
					loadStatisticIntent();

					// Transfer acquired data.
					Statistics.statistics = new StatisticsHelper[4];
					Statistics.statistics = stats;
				} catch (Exception e) {
					// Do nothing.
				}
			}
			else{
				Toast.makeText(Menu.context, R.string.ErrorMessageStatsDownloadFailed, 2000).show();
			}

			// Leave loading screen in any case.
			closeLoading();
		}
	}

	// -----------------------------------------------------------------------------
	// Methods.
	// -----------------------------------------------------------------------------

	/**
	 * Method to load the next intent (statistics).
	 */
	public void loadStatisticIntent(){
		Intent statistic = new Intent(this, eHealth.android.client.Statistics.class);
		this.startActivityForResult(statistic, 101);
	}

	/**
	 * Method to close the current intent and be sure that the user won't be able
	 * to get back to it using the 'return' button of their phone.
	 */
	private void closeLoading(){
		this.finish();
	}
}
